package com.main.common.utils.QueryWrapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.main.common.utils.QueryWrapper.SqlConstants;
import org.apache.commons.lang3.StringUtils;
import java.util.*;

public class DynamicQueryBuilder {

    /**
     * 构建支持嵌套条件的 QueryWrapper
     * @param conditionNode 条件树节点，支持以下结构：
     * {
     *   "AND": [ // 嵌套 AND 条件
     *     { "name": { "LIKE": "张" } },
     *     {
     *       "OR": [ // 嵌套 OR 条件
     *         { "age": { "GT": 25 } },
     *         { "status": { "IN": [1,2] } }
     *       ]
     *     }
     *   ]
     * }
     * @return QueryWrapper<T>
     */
    public static <T> QueryWrapper<T> buildQueryWrapper(Map<String, Object> conditionNode) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        buildNestedConditions(queryWrapper, conditionNode);
        return queryWrapper;
    }

    /**
     * 递归构建嵌套条件
     */
    private static <T> void buildNestedConditions(QueryWrapper<T> queryWrapper, Map<String, Object> node) {
        for (Map.Entry<String, Object> entry : node.entrySet()) {
            String operator = entry.getKey();
            Object value = entry.getValue();

            switch (operator) {
                case SqlConstants.AND:
                case SqlConstants.OR:
                    handleLogicalOperator(queryWrapper, operator, (List<Map<String, Object>>) value);
                    break;
                default:
                    handleFieldCondition(queryWrapper, operator, value);
            }
        }
    }

    /**
     * 处理逻辑运算符 (AND/OR)
     */
    private static <T> void handleLogicalOperator(QueryWrapper<T> wrapper, String operator, List<Map<String, Object>> children) {
        if (SqlConstants.AND.equals(operator)) {
            wrapper.and(qw -> {
                for (Map<String, Object> child : children) {
                    buildNestedConditions((QueryWrapper<T>) qw, child);
                }
            });
        } else if (SqlConstants.OR.equals(operator)) {
            wrapper.or(qw -> {
                for (Map<String, Object> child : children) {
                    buildNestedConditions((QueryWrapper<T>) qw, child);
                }
            });
        }
    }

    /**
     * 处理字段条件
     */
    private static <T> void handleFieldCondition(QueryWrapper<T> wrapper, String field, Object conditionDef) {
        if (conditionDef instanceof Map) {
            Map<String, Object> conditions = (Map<String, Object>) conditionDef;
            for (Map.Entry<String, Object> condEntry : conditions.entrySet()) {
                String operator = condEntry.getKey();
                Object value = condEntry.getValue();
                applyCondition(wrapper, field, operator, value);
            }
        }
    }

    /**
     * 应用单个条件到 QueryWrapper（增强版）
     */
    private static <T> void applyCondition(QueryWrapper<T> queryWrapper, String field, String operator, Object value) {
        switch (operator) {
            case SqlConstants.EQ:
                queryWrapper.eq(field, value);
                break;
            case SqlConstants.NE:
                queryWrapper.ne(field, value);
                break;
            case SqlConstants.GT:
                queryWrapper.gt(field, value);
                break;
            case SqlConstants.GE:
                queryWrapper.ge(field, value);
                break;
            case SqlConstants.LT:
                queryWrapper.lt(field, value);
                break;
            case SqlConstants.LE:
                queryWrapper.le(field, value);
                break;
            case SqlConstants.LIKE:
                queryWrapper.like(field, value);
                break;
            case SqlConstants.START_WITH:
                queryWrapper.likeRight(field, value);
                break;
            case SqlConstants.END_WITH:
                queryWrapper.likeLeft(field, value);
                break;
            case SqlConstants.IN:
                if (value instanceof Collection) {
                    queryWrapper.in(field, (Collection<?>) value);
                }
                break;
            case SqlConstants.NOT_IN:
                if (value instanceof Collection) {
                    queryWrapper.notIn(field, (Collection<?>) value);
                }
                break;
            case SqlConstants.BETWEEN_AND:
                if (value instanceof Object[] && ((Object[]) value).length == 2) {
                    Object[] range = (Object[]) value;
                    queryWrapper.between(field, range[0], range[1]);
                }
                break;
            case SqlConstants.IS_NULL:
                queryWrapper.isNull(field);
                break;
            case SqlConstants.IS_NOT_NULL:
                queryWrapper.isNotNull(field);
                break;
            default:
                throw new IllegalArgumentException("不支持的查询操作符: " + operator);
        }
    }
}